package worm

import (
    "github.com/astaxie/beego/logs"
    "cloud_worm/wormweb/controllers/ctrconfig"
    "cloud_worm/util/uhttp"
    "cloud_worm/util/umodels/mysqldb"
    "cloud_worm/util/umodels/mysqldb/dbmanager"
    "cloud_worm/wormweb/controllers/ctrutil"
    "cloud_worm/util/proto/urpc"
    "time"
    "fmt"
    "strings"
)

type AccessSrvController struct {
    ctrconfig.LoginCtr
}

func (ws *AccessSrvController) Get()  {
    ws.Manager()

    offset, limit := ws.DealPage()
    status, err := ws.GetInt("status", mysqldb.StatusAll)
    version, err := ws.GetInt("version", mysqldb.SelectIntAll)
    domain := ws.GetString("domain")

    // 查询数据
    server := &dbmanager.AccessSrv{}
    count, err := server.SelectCount(status, domain, version)
    if err != nil {
        logs.Error(fmt.Sprintf("get access server count error: %s", err.Error()))
        data := map[string]interface{}{"total": 0, "data": []dbmanager.AccessSrv{}}
        ws.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeSystemErr, "get count error.", data)
        ws.ServeJSON()
        return
    }
    if count == 0 {
        data := map[string]interface{}{"total": count, "data": []dbmanager.AccessSrv{}}
        ws.Data["json"] = uhttp.CreateOkResponse(data)
        ws.ServeJSON()
        return
    }

    servers, err := server.SelectWithStatus(offset, limit, status, domain, version)
    if err != nil {
        logs.Error(fmt.Sprintf("get access server error: %s", err.Error()))
        data := map[string]interface{}{"total": count, "data": []dbmanager.AccessSrv{}}
        ws.Data["json"] = uhttp.CreateOkResponse(data)
        ws.ServeJSON()
        return
    }

    data := map[string]interface{}{"total": count, "data": servers}
    ws.Data["json"] = uhttp.CreateOkResponse(data)
    ws.ServeJSON()
    return
}

// 更新status字段信息
func (ws *AccessSrvController) UpdateStatus()  {
    ws.Manager()

    type InputInfo struct {
        Id          int64       `json:"id"`
        Status      int         `json:"status"`
    }
    var input InputInfo
    if err := ws.Unmarshal(&input); err != nil {
        ws.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeReqBodyErr, err.Error(), nil)
        ws.ServeJSON()
        return
    }
    if input.Status != mysqldb.StatusInvalid && input.Status != mysqldb.StatusValid {
        logs.Warning(fmt.Sprintf("input status error: %d", input.Status))
        ws.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeParamErr, "input status error", nil)
        ws.ServeJSON()
        return
    }

    access := &dbmanager.AccessSrv{Id: input.Id}
    if err := access.Read("id"); err != nil {
        logs.Error(fmt.Sprintf("input id error: %s", err.Error()))
        ws.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeSystemErr, "input id error", nil)
        ws.ServeJSON()
        return
    }
    access.Updated = time.Now().Unix()
    access.Status = input.Status
    if err := access.Update("status", "updated"); err != nil {
        logs.Warning(fmt.Sprintf("input id '%d' update error: %s", input.Id, err.Error()))
        ws.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeSystemErr, "update error", nil)
        ws.ServeJSON()
        return
    }

    ws.Data["json"] = uhttp.CreateOkResponse(nil)
    ws.ServeJSON()
    return
}

func (ws *AccessSrvController) Select()  {
    ws.Manager()

    id, err := ws.GetInt("id")
    if err != nil {
        logs.Warning(fmt.Sprintf("input id error: %s", err.Error()))
        data := map[string]interface{}{"total": 0, "data": []dbmanager.AccessSrv{}}
        ws.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeParamErr, "input id error", data)
        ws.ServeJSON()
        return
    }

    server := &dbmanager.AccessSrv{Id: int64(id)}
    err = server.Read("id")
    if err != nil {
        logs.Warning(fmt.Sprintf("no this id record: %s", err.Error()))
        data := map[string]interface{}{"total": 0, "data": []dbmanager.AccessSrv{}}
        ws.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeParamErr, "no input id record", data)
        ws.ServeJSON()
        return
    }

    var servers []dbmanager.AccessSrv
    servers = append(servers, *server)
    data := map[string]interface{}{"total": 1, "data": servers}
    ws.Data["json"] = uhttp.CreateOkResponse(data)
    ws.ServeJSON()
    return
}

type AccessSrvInfoController struct {
    ctrconfig.LoginCtr
}

func (w *AccessSrvInfoController) Get()  {
    w.Manager()

    inputURL := w.GetString("input_url")
    if inputURL == "" {
        logs.Error(fmt.Sprintf("input url error: %s", inputURL))
        data := map[string]interface{}{"total": 0, "data": []dbmanager.AccessSrv{}}
        w.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeParamErr, "input url error.", data)
        w.ServeJSON()
        return
    }
    inputURL = strings.TrimSuffix(inputURL, "/server/info")
    inputURL = strings.TrimPrefix(inputURL, "https://")

    args := urpc.ServerInfoArgs{}
    reply := urpc.ServerInfoReply{}
    err := ctrutil.AccessSrvRpc.Call(inputURL, "ServerAbout.GetServerInfo", &args, &reply)
    if err != nil {
        logs.Error(fmt.Sprintf("get access server info error: %s", err.Error()))
        data := map[string]interface{}{"total": 0, "data": []dbmanager.AccessSrv{}}
        w.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeSystemErr, "get access server info error", data)
        w.ServeJSON()
        return
    }

    // 检查重复性： todo：mysql语句稍作调整
    server := &dbmanager.AccessSrv {
        Version: reply.Version,
    }
    err = server.Read("version")
    if err == nil {
        // update操作
        server.Domain = reply.Domain
        server.AccessPort = reply.TCPPort
        server.RpcPort = reply.HTTPPort
        server.Updated = time.Now().Unix()
        if err := server.Update("domain", "access_port", "rpc_port", "updated"); err != nil {
            logs.Warning(fmt.Sprintf("update info failed: %s", err.Error()))
            data := map[string]interface{}{"total": 0, "data": []dbmanager.AccessSrv{}}
            w.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeSystemErr, "update info failed", data)
            w.ServeJSON()
            return
        }
    } else {
        // 新的，增新增
        server.Domain = reply.Domain
        server.AccessPort = reply.TCPPort
        server.RpcPort = reply.HTTPPort
        server.Version = reply.Version
        server.Created = time.Now().Unix()
        server.Updated = server.Created
        server.Status = mysqldb.StatusValid
        err = server.Insert()
        if err != nil {
            logs.Error(fmt.Sprintf("insert error: %s", err.Error()))
            data := map[string]interface{}{"total": 0, "data": []dbmanager.AccessSrv{}}
            w.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeSystemErr, "insert error.", data)
            w.ServeJSON()
            return
        }
    }

    var servers []dbmanager.AccessSrv
    servers = append(servers, *server)
    data := map[string]interface{}{"total": 1, "data": servers}
    w.Data["json"] = uhttp.CreateOkResponse(data)
    w.ServeJSON()
    return
}
